package com.zhuoyue.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;


import com.alibaba.fastjson.JSONObject;
import com.zhuoyue.biz.core.api.appjson.automate.json.ExcuteDeviceJson;
import com.zhuoyue.biz.core.api.domain.GatewayDO;
import com.zhuoyue.biz.core.api.dto.rep.AutomateRepDTO;
import com.zhuoyue.biz.core.api.dto.req.AutomateAddDTO;
import com.zhuoyue.biz.core.api.dto.req.AutomateUpdateDTO;
import com.zhuoyue.biz.core.api.service.GatewayService;
import com.zhuoyue.common.aop.auth.CheckLogin;
import com.zhuoyue.common.aop.auth.User;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.zhuoyue.biz.core.api.domain.AutomateDO;
import com.zhuoyue.biz.core.api.service.AutomateService;
import com.zhuoyue.biz.core.api.service.GatewayRedisService;
import com.zhuoyue.biz.core.command.constant.SceneCmdDeal;
import com.zhuoyue.common.dto.ControllerResult;
import com.zhuoyue.common.dto.ResultDTO;
import com.zhuoyue.common.utils.CmdUtils;
import org.apache.commons.lang3.StringUtils;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@RestController
@Scope("prototype")
@RequestMapping("/api/automate")
@Validated
@Slf4j(topic = "Automate")
/**
 * @ClassName: AppAutomateController
 * @Description:自动化控制
 * @author wjming
 * @Date 2021/2/14 19:25
 */
public class AppAutomateController {

    @Autowired
    private AutomateService automateService;

    @Autowired
    private GatewayRedisService gatewayRedisService;

    @Autowired
    private GatewayService gatewayService;

    /**
     * 查询家庭中的自动化列表
     *
     * @param homeId
     * @return
     */
    @GetMapping("/list")
    @CheckLogin
    public ControllerResult getAutomateList(@NotBlank(message = "家庭ID不能为空") String homeId, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getAutomateList] -> [homeId:{}]", user.getAccount(), user.getOrgCode(), homeId);

        //根据homeId查询网关信息
        GatewayDO gatewayDO = gatewayService.getByHomeId(homeId);
        if (gatewayDO == null) {
            return ControllerResult.toParamFail("请先添加网关");
        }
        List<AutomateDO> result = automateService.getAutomateListByGatewayMac(gatewayDO.getZigbeeMac());
        List<AutomateRepDTO> automateRepDtoS = new ArrayList<>();
        result.stream().forEach(list -> {
            automateRepDtoS.add(returnDTO(list));
        });

        //日志
        Integer automateSize = 3;
        if (automateRepDtoS.size() > automateSize) {
            log.info("result -> [getAutomateList] -> [{}]", automateRepDtoS.stream().map(automateRepDto -> automateRepDto.getId()).collect(Collectors.toList()));
        } else {
            log.info("result -> [getAutomateList] -> [{}]", automateRepDtoS);
        }

        return ControllerResult.toReturnDataSuccess("获取成功", automateRepDtoS);
    }


    /**
     * 自动化添加
     *
     * @param automateAddDTO
     * @return
     */
    @PostMapping("/add")
    @CheckLogin
    public ControllerResult addAutomate(@Valid @RequestBody AutomateAddDTO automateAddDTO, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addAutomate] -> [automateAddDTO:{}]", user.getAccount(), user.getOrgCode(), JSONObject.toJSONString(automateAddDTO));
        //根据homeId查询网关信息
        GatewayDO gatewayDO = gatewayService.getByHomeId(automateAddDTO.getHomeId());
        if (gatewayDO == null) {
            return ControllerResult.toParamFail("请先添加网关");
        }
        AutomateDO automate = new AutomateDO();
        BeanUtils.copyProperties(automateAddDTO, automate);
        automate.setGatewayMac(gatewayDO.getZigbeeMac());
        automate.setTriggerTime(StringUtils.isEmpty(automateAddDTO.getTriggerTime()) ? "0018" : automateAddDTO.getTriggerTime());

        automate.setAutomateType(automateAddDTO.getAutomateType() == null ? 0 : automateAddDTO.getAutomateType());
        automate.setTriggerType(automateAddDTO.getTriggerType() == null ? 0 : automateAddDTO.getTriggerType());
        AutomateDO automateDO = automateService.addAutomate(automate);
        AutomateRepDTO automateRepDTO = returnDTO(automateDO);
        log.info("result -> [addAutomate] -> [{}]", automateRepDTO);
        return ControllerResult.toReturnDataSuccess("添加成功", automateRepDTO);
    }

    /**
     * 自动化信息修改
     *
     * @param automateUpdateDTO
     * @return
     */
    @PutMapping("/modify")
    @CheckLogin
    public ControllerResult updateAutomate(@Validated @RequestBody AutomateUpdateDTO automateUpdateDTO, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [updateAutomate] -> [automateUpdateDTO:{}]", user.getAccount(), user.getOrgCode(), JSONObject.toJSONString(automateUpdateDTO));
        AutomateDO automate = new AutomateDO();
        BeanUtils.copyProperties(automateUpdateDTO, automate);
        if (automateUpdateDTO.getTriggerType() != null) {
            automate.setTriggerType(automateUpdateDTO.getTriggerType());
        }
        AutomateDO result = automateService.updateAutomateById(automate);
        AutomateRepDTO automateRepDTO = returnDTO(result);
        log.info("result -> [updateAutomate] -> [{}]", automateRepDTO);
        return ControllerResult.toReturnDataSuccess("修改成功", automateRepDTO);
    }

    /**
     * 自动化删除
     *
     * @param id 自动化ID
     * @return
     */
    @DeleteMapping("/delete")
    @CheckLogin
    public ControllerResult deleteAutomate(@RequestParam @NotBlank(message = "自动化ID不能为空！") String id, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [deleteAutomate] -> [automateId:{}]", user.getAccount(), user.getOrgCode(), id);
        ResultDTO<AutomateDO> getRes = automateService.getAutomateById(id);
        if (!getRes.isExist()) {
            return ControllerResult.toOtherFail(getRes.getErrorDetail(), getRes.getResultCode());
        }

        if (getRes.getModule().getAutomateType() == 0) {
            String automateClearCmd = getAutomateClearCmd(getRes.getModule().getGatewayMac(), getRes.getModule().getCode() + "");
            // 发送指令
            gatewayRedisService.writeDataToGateway(getRes.getModule().getGatewayMac(), automateClearCmd);
        }
        automateService.deleteAutomateById(id);
        return ControllerResult.toReturnMessageSuccess("删除成功");
    }


    /**
     * 远程组合场景控制
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/remote", method = RequestMethod.POST)
    @CheckLogin
    public ControllerResult remoteAutoMate(@NotBlank(message = "远程场景ID不能为空") String id, HttpServletRequest request) throws InterruptedException {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [remoteAutoMate] -> [remoteId:{}]", user.getAccount(), user.getOrgCode(), id);
        ResultDTO<AutomateDO> automateById = automateService.getAutomateById(id);
        String executeDeviceState = automateById.getModule().getExecuteDeviceState();
        JSONArray jsonarray = JSONArray.fromObject(executeDeviceState);
        List<ExcuteDeviceJson> list = (List) JSONArray.toCollection(jsonarray, ExcuteDeviceJson.class);
        if (list.size() < 1) {
            return ControllerResult.toParamFail("设备已删除");
        }
        for (int i = 0; i < list.size(); i++) {
            String cmd = list.get(i).getCmd();
            String gatewayMac = list.get(i).getControlParam().getGatewayMac();
            Thread.sleep(250);
            gatewayRedisService.writeDataToGateway(gatewayMac, cmd);
        }
        log.info("result -> user:[{}_{}] [remoteAutoMate] -> [{}]", user.getAccount(), user.getOrgCode(), list.stream().map(a -> a.getCmd()).collect(Collectors.toList()));
        return ControllerResult.toReturnMessageSuccess("控制成功");
    }

    private String getAutomateClearCmd(String gatewayMac, String code) {

        String cmd3To8 = "50" +
                SceneCmdDeal.SceneClear.CMD_4 +
                gatewayMac +
                SceneCmdDeal.SceneClear.CMD_6 +
                SceneCmdDeal.SceneClear.CMD_7 +
                CmdUtils.intToHexTwo(Integer.parseInt(code));

        String cmd2 = CmdUtils.getDateLength(cmd3To8);

        String cmd9 = CmdUtils.getCmdBodySum(cmd3To8);

        String fullCmd = SceneCmdDeal.SceneClear.CMD_1 +
                cmd2 +
                cmd3To8 +
                cmd9 +
                SceneCmdDeal.SceneClear.CMD_10;

        return fullCmd;

    }

    private AutomateRepDTO returnDTO(AutomateDO automateDO) {
        AutomateRepDTO automateRepDTO = new AutomateRepDTO();
        BeanUtils.copyProperties(automateDO, automateRepDTO);
        automateRepDTO.setCreateTime(automateDO.getCreateTime());
        return automateRepDTO;
    }

}
